define(["require", "exports", "../class/Tween", "../class/When", "./Snake", "./Food", "./common"], function (require, exports, Tween_1, When_1, Snake_1, Food_1, common_1) {
    "use strict";
    exports.ani_ticker = new PIXI.ticker.Ticker();
    exports.ani_tween = new Tween_1.default();
    exports.jump_tween = new Tween_1.default();
    exports.ani_ticker.add(function () {
        exports.ani_tween.update();
        exports.jump_tween.update();
    });
    exports.current_stage = new PIXI.Container();
    //加载图片资源
    exports.loader = new PIXI.loaders.Loader();
    exports.loader.add("zz", "/images/snake.jpg");
    exports.loader.add("bg", "/images/bg45.jpg");
    exports.loader.add('bg_diffuse', '/images/bg66.jpg');
    exports.loader.add('bg_normal', '/images/bg66_normal.jpg');
    // path_datas.forEach((path_data, i) => {
    //     loader.add(path_data.src, path_data.src);
    // });
    // article_datas.forEach((article_data, i) => {
    //     if (article_data.type === "image") {
    //         loader.add(article_data.content, article_data.content);
    //     }
    // });
    exports.loader.load();
    var loading_text = new PIXI.Text("加载中……", { font: "25px 微软雅黑", fill: "#FFF" });
    loading_text.x = common_1.VIEW_WIDTH / 2 - loading_text.width / 2;
    loading_text.y = common_1.VIEW_HEIGHT / 2 - loading_text.height / 2;
    exports.current_stage.addChild(loading_text);
    exports.loader.on("progress", function (loader, resource) {
        loading_text.text = "\u52A0\u8F7D\u4E2D: " + loader.progress + "%";
        loading_text.x = common_1.VIEW_WIDTH / 2 - loading_text.width / 2;
        loading_text.y = common_1.VIEW_HEIGHT / 2 - loading_text.height / 2;
    });
    exports.loader.once("complete", renderInit);
    /**
     * 数据同步
     * 提供请求花费的时间，通过这个时间来加速本地的效果，从而模拟出当前服务器上的效果
     */
    function syncServerData(route, data, callback) {
        var _start_time = Date.now();
        pomelo.request(route, data, function (res_data) {
            if (res_data.code === 500) {
                console.error("ERROR!", route, data, res_data);
                return;
            }
            // console.log("ping:", Date.now() - _start_time)
            callback(res_data, function () { return Date.now() - _start_time; });
        });
    }
    ;
    var battlefield_view_width = common_1.VIEW_WIDTH;
    var battlefield_view_height = common_1.VIEW_HEIGHT;
    function renderInit(loader, resource) {
        exports.current_stage.removeChild(loading_text);
        /**背景贴图 */
        var bg_img = new PIXI.extras.TilingSprite(resource["bg"].texture, common_1.VIEW_WIDTH, common_1.VIEW_HEIGHT);
        // bg_img["normalTexture"] = resource["bg_normal"].texture;
        exports.current_stage.addChild(bg_img);
        var unit_normal_tex = resource["bg_normal"].texture;
        var unit_diffuse_tex = resource["bg_diffuse"].texture;
        // var bg_img = new TilingSprite(unit_diffuse_tex, VIEW_WIDTH, VIEW_HEIGHT, null, null, { y: -5 })
        // bg_img["normalTexture"] = TextureGenerator(renderer, current_stage, unit_normal_tex, bg_img.texture.width, bg_img.texture.height, bg_img.tile_offset_x, bg_img.tile_offset_y)
        // current_stage.addChild(bg_img);
        // 战场基本信息
        var battlefield_level = 2;
        var battlefield_width = Math.pow(2, battlefield_level) * Food_1.FOOD_CONTAINER_UNIT_SIZE;
        var battlefield_height = Math.pow(2, battlefield_level) * Food_1.FOOD_CONTAINER_UNIT_SIZE;
        exports.current_stage.addChild(new PIXI.lights.AmbientLight(null, 1.5));
        //生成战场
        var battlefield = new PIXI.Container();
        exports.current_stage.addChild(battlefield);
        bg_img.tilePosition = battlefield.position;
        // 生成蛇容器
        var random_start_point_x = 0; //battlefield_width * Math.random()
        var random_start_point_y = 0; //battlefield_height * Math.random()
        var snakes = new Snake_1.SnakeContainer();
        battlefield.addChild(snakes);
        // 食物容器
        var foods = new Food_1.FoodContainer();
        exports.current_stage.addChild(foods);
        //测试背景贴图
        // var bg_normal = new PIXI.Sprite(resource["bg"].texture);
        // bg_normal.anchor.set(.5, .5);
        // bg_normal["normalTexture"] = resource["bg_normal"].texture;
        // battlefield.addChild(bg_normal);
        // ani_ticker.add(() => {
        //     var head_point = my_snake.getHeadPoint();
        //     bg_normal.position = my_snake.getHeadPoint();
        // });
        var my_snake;
        function my_snake_init(snake_info) {
            my_snake = new Snake_1.default({
                body: {
                    offset: { x: 0, y: 0 },
                    length: 30,
                    points: Array.apply(null, { length: 10 }).map(function (v, i) {
                        return { x: i, y: i };
                    })
                },
                density: 20,
                speed: 15,
                sensitivity: 360,
                direction: 180
            });
            my_snake.importData(snake_info);
            // 生成第一视角蛇
            battlefield.addChild(my_snake);
            exports.ani_ticker.add(function () {
                my_snake.run();
                var current_stage_scale = 25 / my_snake._density;
                current_stage_scale < 1 && (current_stage_scale = 1);
                exports.current_stage.scale.set(current_stage_scale, current_stage_scale);
                var head_point = my_snake.getHeadPoint();
                battlefield_view_width = common_1.VIEW_WIDTH / current_stage_scale;
                battlefield_view_height = common_1.VIEW_HEIGHT / current_stage_scale;
                exports.ani_tween.Tween("battlefield", battlefield)
                    .to({
                    x: -head_point.x + battlefield_view_width / 2,
                    y: -head_point.y + battlefield_view_height / 2
                }, common_1.S_ANI_TIME)
                    .start();
                // battlefield.x = 
                // battlefield.y =
                foods.updatePos(battlefield.x, battlefield.y, my_snake._speed);
                //更新战场信息
                _deg_log.text = "FPS:" + exports.ani_ticker.FPS.toFixed(2) + "\n                        NAME:" + my_snake._id + "\n                        X:" + head_point.x.toFixed(5).substr(0, 7) + "\n                        Y:" + head_point.y.toFixed(5).substr(0, 7) + "\n                        \u957F\u5EA6Body:" + my_snake._body.length + "\n                        \u957F\u5EA6\u9AA8\u8282\u6570:" + my_snake._body.points.length + "\n                        \u957F\u5EA6\u9AA8\u8282\u957F\u5EA6:" + my_snake._base_spacing + "\n                        \u8170\u56F4Density:" + my_snake._density + "\n                        \u901F\u5EA6Speed:" + my_snake._speed.toFixed(5).substr(0, 7) + "\n                        \u65B9\u5411Direction:" + my_snake._direction.toFixed(5).substr(0, 7) + "\n                        " + -1 / Math.tan((my_snake._direction / 180 - 0.5) * Math.PI) + "\n                        \u7075\u654F\u5EA6Sensitivity:" + my_snake._sensitivity.toFixed(5).substr(0, 7) + "\n                        \u884C\u4E3A\u9884\u6D4B:" + _is_Behavior_Prediction + "\n                        \u662F\u5426\u987A\u65F6\u9488:" + my_snake._is_clockwise + "\n                        " + (my_snake._is_use_pre_points ? "补帧" : "跳帧") + "\n                        ";
                _deg_log.scale.set(1 / current_stage_scale, 1 / current_stage_scale);
                // //背景贴图位移
                // bg_img.tilePosition = battlefield.position
            });
            my_snake.viewSnake(snakes);
            //死亡监听
            var _send_die = false;
            my_snake.on("died", function (hit_snake) {
                if (_send_die) {
                    return;
                }
                _send_die = true;
                console.log("发送死亡信息");
                syncServerData("chat.chatHandler.dieSnake", {
                    killer_id: hit_snake[0]._id
                }, function (data) {
                    if (data.success) {
                        console.log("you died!");
                    }
                    //exit to re enter
                });
            });
            my_snake.viewFoods(foods);
            my_snake_inited(my_snake);
            // my_snake.alpha = 0.5
            return my_snake;
        }
        function my_snake_inited(my_snake) {
            /**缓存战场数据的范围·宽度 */
            var battlefield_cache_data_width = common_1.VIEW_WIDTH * 4;
            /**缓存战场数据的范围·高度 */
            var battlefield_cache_data_height = common_1.VIEW_HEIGHT * 4;
            /**目前战场数据的起点·X */
            var battlefield_cache_data_x;
            /**目前战场数据的起点·Y */
            var battlefield_cache_data_y;
            function getRangeFoods(center_point, cb) {
                battlefield_cache_data_x = center_point.x - battlefield_cache_data_width / 2;
                battlefield_cache_data_y = center_point.y - battlefield_cache_data_height / 2;
                syncServerData("chat.chatHandler.getRangeFoods", {
                    x: battlefield_cache_data_x,
                    y: battlefield_cache_data_y,
                    width: battlefield_cache_data_width,
                    height: battlefield_cache_data_height,
                }, function (data) {
                    if (data.foods) {
                        foods._particle_foods = [];
                        foods.clearParticleFood();
                        data.foods.forEach(function (food_info) {
                            foods.addParticleFood(new Food_1.FoodEffect(food_info.effect), food_info.x, food_info.y);
                        });
                        cb && cb(data);
                    }
                });
            }
            //初始化食物数据
            getRangeFoods(my_snake.getHeadPoint());
            var ping = 100; //网络延迟的毫秒数
            var VIEW_WIDTH_2 = common_1.VIEW_WIDTH / 2;
            var VIEW_HEIGHT_2 = common_1.VIEW_HEIGHT / 2;
            exports.ani_ticker.add(function () {
                // 缓存数据所需的边境
                var cache_check_range = (ping + 500 /*假设下载数据需要500ms*/) * 0.001 * my_snake._speed;
                var head_point = my_snake.getHeadPoint();
                if (head_point.x - VIEW_WIDTH_2 < battlefield_cache_data_x ||
                    head_point.y - VIEW_HEIGHT_2 < battlefield_cache_data_y ||
                    head_point.x + VIEW_WIDTH_2 + cache_check_range > battlefield_cache_data_x + battlefield_cache_data_width ||
                    head_point.y + VIEW_HEIGHT_2 + cache_check_range > battlefield_cache_data_y + battlefield_cache_data_height) {
                    getRangeFoods(head_point);
                }
            });
            /**进食 */
            function eatFoods(foods, cb) {
                syncServerData("chat.chatHandler.eatFoods", {
                    foods: foods
                }, function (data, get_delay_time) {
                    cb && cb(data);
                    // _is_Behavior_Prediction && my_snake.update(get_delay_time());
                });
            }
            // 触发吃食物
            my_snake.on("eated_food", function (eated_points) {
                my_snake.waitingForImportData();
                var points = eated_points.map(function (food) {
                    return {
                        x: food.x,
                        y: food.y
                    };
                });
                eatFoods(points, function (data) {
                    my_snake.importData(data);
                });
            });
            init_w.ok(0, []);
        }
        ;
        var _deg_log = new PIXI.Text("", { font: "16px 微软雅黑", fill: "#0FF" });
        exports.current_stage.addChild(_deg_log);
        // var mask = SVGGraphics.importFromSVG(`<rect x="0" y="0" width="${VIEW_WIDTH}" height="${VIEW_HEIGHT}" fill="rgba(255,255,255,${0.2})" stroke-width="0"/>`)._graphics;
        var mask = new PIXI.Sprite(resource["bg_normal"].texture);
        mask.width = common_1.VIEW_WIDTH;
        mask.height = common_1.VIEW_HEIGHT;
        mask.alpha = 0;
        exports.current_stage.addChild(mask);
        mask.interactive = true;
        var _is_loading_data = false;
        var _is_Behavior_Prediction = true;
        common_1.on(mask, "mousemove|tap", function (e) {
            if (!my_snake) {
                return;
            }
            if (_is_loading_data || my_snake._delay_deg) {
                return;
            }
            var click_point = e.data.getLocalPosition(this.parent);
            var deg = Math.atan2(click_point.x - battlefield_view_width / 2, click_point.y - battlefield_view_height / 2);
            if (deg < 0) {
                deg = Math.PI * 2 + deg;
            }
            deg = deg / Math.PI * 180;
            // my_snake.turnHead(deg);
            _is_loading_data = true;
            //蛇的速度变慢，以避免服务端数据返回的时候的跳跃感
            my_snake.waitingForImportData();
            syncServerData("chat.chatHandler.turnMySnakeHead", {
                deg: deg,
            }, function (data, get_delay_time) {
                // my_snake.importData(data);
                // _is_Behavior_Prediction && my_snake.update(get_delay_time());
                _is_loading_data = false;
            });
        });
        common_1.on(mask, "mousedown", function (e) {
            _is_Behavior_Prediction = !_is_Behavior_Prediction;
        });
        var is_sprinting = false;
        common_1.on(mask, "mousedown", function (e) {
            if (!my_snake) {
                return;
            }
            syncServerData("chat.chatHandler.snakeSprint", {}, function (is_success) {
                if (is_success) {
                    console.log("冲刺成功");
                    is_sprinting = true;
                }
                else {
                    console.log("冲刺失败");
                }
            });
        });
        common_1.on(mask, "mouseup|mouseover", function (e) {
            if (!my_snake || !is_sprinting) {
                return;
            }
            syncServerData("chat.chatHandler.stopSnakeSprint", {}, function (is_success) {
                console.log(is_success ? "停止冲刺" : "停止冲刺失败");
            });
        });
        // 远程数据相关
        function showError(error) {
            console.log(error);
        }
        function queryEntry(uid, callback) {
            var route = 'gate.gateHandler.queryEntry';
            pomelo.init({
                host: window.location.hostname,
                port: 3014,
                log: false
            }, function () {
                pomelo.request(route, {
                    uid: uid
                }, function (data) {
                    // pomelo.disconnect();
                    if (data.code === 500) {
                        showError("登陆失败");
                        return;
                    }
                    callback(data.host, data.port);
                });
            });
        }
        ;
        var username = "gaubee-" + Math.random().toString(36).substr(2);
        var rid = "fangjian-1";
        queryEntry(username, function (host, port) {
            pomelo.init({
                host: host,
                port: port,
                log: false
            }, function () {
                var route = "connector.entryHandler.enter";
                pomelo.request(route, {
                    username: username,
                    rid: rid
                }, function (data) {
                    if (data.error) {
                        showError("重复登陆！");
                        return;
                    }
                    initSnake();
                });
            });
        });
        function initSnake() {
            syncServerData("chat.chatHandler.getMySnake", {
                rid: rid,
                from: username
            }, function (data, get_delay_time) {
                // battlefield.emit("my_snake_init", data);
                var snake = my_snake_init(data);
                _is_Behavior_Prediction && snake.update(get_delay_time());
            });
            syncServerData("chat.chatHandler.getOtherSnakes", {
                rid: rid,
                from: username
            }, function (data, get_delay_time) {
                data.snakes && data.snakes.forEach(function (snake_data) {
                    var new_snake = joinSnake(snake_data);
                    _is_Behavior_Prediction && new_snake.update(get_delay_time());
                });
            });
        }
        pomelo.on("turnHead", function (data) {
            if (data.id === my_snake._id) {
                my_snake.importData(data);
            }
            else {
                snakes.children.forEach(function (snake) {
                    snake._id === data.id && snake.importData(data);
                });
            }
        });
        function joinSnake(new_snake_data) {
            var new_snake = new Snake_1.default({
                body: {
                    offset: { x: 0, y: 0 },
                    length: 20,
                    points: Array.apply(null, { length: 3 }).map(function (v, i) {
                        return { x: 0, y: 0 };
                    })
                },
                density: 20,
                speed: 10,
                sensitivity: 360,
                direction: 0
            });
            exports.ani_ticker.add(function () {
                // new_snake._direction = (new_snake._direction + Math.random() * 5) % 360;
                new_snake.run();
            });
            new_snake.importData(new_snake_data);
            snakes.addSnake(new_snake);
            return new_snake;
        }
        ;
        pomelo.on("joinSnake", function (new_snake_data) {
            if (my_snake._id === new_snake_data.id) {
                return;
            }
            joinSnake(new_snake_data);
        });
        pomelo.on("foodBeEated", function (data) {
            var snake_data = data.snake;
            if (snake_data.id === my_snake._id) {
                return;
            }
            snakes.children.some(function (snake) {
                if (snake._id === snake_data.id) {
                    snake.importData(snake_data);
                    return true;
                }
            });
            data.foods.forEach(function (food_info) {
                foods.removeParticleFood(food_info.x, food_info.y);
            });
        });
        pomelo.on("dieSnake", function (data) {
            if (data.snake_id === my_snake._id) {
                my_snake.die();
            }
            else {
                snakes.children.some(function (snake) {
                    if (snake._id === data.snake_id) {
                        snake.die();
                        return true;
                    }
                });
            }
            data.foods.forEach(function (food_info) {
                foods.addParticleFood(new Food_1.FoodEffect(food_info.effect), food_info.x, food_info.y);
            });
        });
        pomelo.on("burnSnake", function (data) {
            data.foods.forEach(function (food_info) {
                foods.addParticleFood(new Food_1.FoodEffect(food_info.effect), food_info.x, food_info.y);
            });
            if (data.snake_id === my_snake._id) {
                my_snake._delay_num -= data.burn_body;
            }
            else {
                snakes.children.some(function (snake) {
                    if (snake._id === data.snake_id) {
                        snake._delay_num -= data.burn_body;
                        return true;
                    }
                });
            }
        });
        function importSnakeData(data) {
            if (data.id === my_snake._id) {
                my_snake.importData(data);
            }
            else {
                snakes.children.some(function (snake) {
                    if (snake._id === data.id) {
                        snake.importData(data);
                        return true;
                    }
                });
            }
        }
        ;
        pomelo.on("snakeSprint", importSnakeData);
        pomelo.on("snakeStopSprint", importSnakeData);
    }
    exports.current_stage.on("init", initStage);
    var init_w = new When_1.default(2, function () {
        exports.ani_tween.start();
        exports.jump_tween.start();
        exports.ani_ticker.start();
    });
    function initStage() {
        init_w.ok(1, []);
    }
    exports.initStage = initStage;
});
